package com.easylinkin.sm.context;

import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.easylinkin.sm.entity.Customer;
import com.easylinkin.sm.entity.Department;
import com.easylinkin.sm.entity.Menu;
import com.easylinkin.sm.entity.Privilege;
import com.easylinkin.sm.entity.Role;
import com.easylinkin.sm.entity.User;

import lombok.Data;
import lombok.EqualsAndHashCode;
import site.morn.framework.context.dto.BaseLoginInfo;
import site.morn.framework.entity.BasePrivilege;
import site.morn.framework.entity.BaseRole;
import site.morn.util.GenericUtils;

/**
 * 登录信息
 *
 * <p>扩展用户模块相关信息
 *
 * @author TianGanLin
 * @since 1.0.0, 2019/10/11
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class SmLoginInfo extends BaseLoginInfo {

  /**
   * 登录用户
   */
  private User user;

  /**
   * 客户
   */
  private Customer customer;

  /**
   * 所属机构
   */
  private Department department;

  /**
   * 菜单
   */
  private List<Menu> menus;

  @Override
  public List<Role> getRoles() {
    Function<BaseRole, Role> cast = role -> cast(role, Role.class);
    return super.getRoles().stream().map(cast).collect(Collectors.toList());
  }

  @Override
  public List<Privilege> getPrivileges() {
    Function<BasePrivilege, Privilege> cast = role -> cast(role, Privilege.class);
    return super.getPrivileges().stream().map(cast).collect(Collectors.toList());
  }

  /**
   * 强制转换
   *
   * @param source 源对象
   * @param type 目标类
   * @param <S> 原类型
   * @param <T> 目标类型
   * @return 目标对象
   */
  private <S, T> T cast(S source, Class<?> type) {
    if (type.isAssignableFrom(source.getClass())) {
      return GenericUtils.castFrom(source);
    }
    return null;
  }
}
